package com.li.configserve.config.globalexception;

import com.li.configserve.domain.gloabreturn.ResponseInfo;
import com.li.configserve.domain.gloabreturn.ResultEnum;
import com.li.toolkit.constant.LogConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletResponse;

/**
 * 异常处理器
 *
 * @author LiDong
 * @RestControllerAdvice 代替 @ControllerAdvice 这样在方法上就可以不需要添加 @ResponseBody
 */
@RestControllerAdvice(basePackages = "com.li")
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 全局异常处理器：所有的异常在这里捕获进行处理
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ResponseInfo<Object> globalExceptionHandler(Exception e, HttpServletResponse response) {
        ResponseInfo<Object> responseInfo = new ResponseInfo<>();
        logger.error(LogConst.ERROR, e);
        // 判断是否为 MyException 异常
        if (e instanceof MyException) {
            // 设置 HTTP 状态码
            response.setStatus(HttpStatus.BAD_REQUEST.value());
            // 返回错误信息
            responseInfo.setCode(ResultEnum.PARAMETER_ERROR.getCode());
            responseInfo.setMessage(e.getMessage());
            return responseInfo;
        }
        // 判断是否为 NotFountResourceException 异常
        if (e instanceof NotFountResourceException) {
            response.setStatus(HttpStatus.BAD_REQUEST.value());
            responseInfo.setCode(ResultEnum.NOT_FOUNT_RESOURCE.getCode());
            responseInfo.setMessage(e.getMessage());
            return responseInfo;
        }
        // 判断是否为丢失请求参数异常
        if (e instanceof MissingServletRequestParameterException) {
            response.setStatus(HttpStatus.BAD_REQUEST.value());
            responseInfo.setCode(ResultEnum.PARAMETER_MISSING_ERROR.getCode());
            responseInfo.setMessage(ResultEnum.PARAMETER_MISSING_ERROR.getMessage());
            return responseInfo;
        }

        // 判断是否为请求参数错误异常
        if (e instanceof MethodArgumentNotValidException) {
            response.setStatus(HttpStatus.BAD_REQUEST.value());
            responseInfo.setCode(ResultEnum.PARAMETER_ERROR.getCode());
            responseInfo.setMessage(ResultEnum.PARAMETER_ERROR.getMessage());
            return responseInfo;
        }
        if (e instanceof NullPointerException) {
            response.setStatus(HttpStatus.OK.value());
            responseInfo.setCode(ResultEnum.NULL_POINTER.getCode());
            responseInfo.setMessage(ResultEnum.NULL_POINTER.getMessage());
            return responseInfo;
        }
        // 捕获没有登录的异常
        if (e instanceof NoLoginException) {
            response.setStatus(ResultEnum.NOLOGGING.getCode());
            responseInfo.setCode(ResultEnum.NOLOGGING.getCode());
            responseInfo.setMessage(ResultEnum.NOLOGGING.getMessage());
            return responseInfo;
        }
        // Token出错：没有登录
        if (e instanceof TokenErrorException) {
            response.setStatus(ResultEnum.NOLOGGING.getCode());
            responseInfo.setCode(ResultEnum.NOLOGGING.getCode());
            responseInfo.setMessage(ResultEnum.NOLOGGING.getMessage());
            return responseInfo;
        }
        if (e instanceof NumberFormatException) {
            responseInfo.setMessage("数值类型转换出错：" + e.getMessage());
        }
        // response 设置响应码
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        // 返回自己定义的 responseInfo 对象
        responseInfo.setCode(ResultEnum.UNKNOWN_ERROR.getCode());
        responseInfo.setMessage(e.getMessage());
        return responseInfo;
    }

}